import asyncio
import logging
import threading
from pyredis.redis_helper import RedisHelper, CHANNEL_API_SERVER, CHANNEL_SPIDER
from DataManager import DataManager, DATABASE_PATH


class RadiocacaManager(object):
    def __init__(self):
        self.mutex = threading.Lock()
        self.handlers = {}
        self.redis_helper = None
        self.database = DataManager("../" + DATABASE_PATH)
        self.database.init_shop_dataBase()
        self.last_data = {
            "market_place": self.database.get_latest_stat(),
            "price_limit": self.database.get_price_limit(),
            "switch": self.database.get_switch(),
            "buy_now": self.database.get_buy_now()
        }

    def start(self):
        logging.info("start")
        self.redis_helper = RedisHelper(sub_obj=self, auto_init=True, sub_thread_init=True, sub_channel=CHANNEL_API_SERVER)

    def register(self, m_id, handler):
        self.mutex.acquire()
        logging.info("register " + m_id)
        self.handlers[m_id] = handler
        self.mutex.release()

    def unregister(self, m_id):
        self.mutex.acquire()
        logging.info("unregister " + m_id)
        try:
            self.handlers.pop(m_id)
        except:
            pass
        self.mutex.release()

    def pub_spider_loginfo(self, msg):
        logging.info("pub_spider_loginfo")
        # 这个函数是通过redis_sub回调的，不在torando管理event_loop中，在handle执行wirte_meesage时会报错
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        self.mutex.acquire()
        for key, handler in self.handlers.items():
            try:
                handler.send_msg("pub_spider_loginfo", msg)
            except:
                pass
        self.mutex.release()

    def update_buy_now(self, msg):
        logging.info("update_buy_now")
        # 这个函数是通过redis_sub回调的，不在torando管理event_loop中，在handle执行wirte_meesage时会报错
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        self.last_data["buy_now"] = msg
        self.send_msg("buy_now", msg)

    def update_market_place(self, msg):
        logging.info("update_market_place")
        # 这个函数是通过redis_sub回调的，不在torando管理event_loop中，在handle执行wirte_meesage时会报错
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        self.last_data["market_place"] = msg
        self.send_msg("market_place", msg)

    def update_database(self, func, data):
        fun = getattr(self.database, func, None)
        if fun:
            fun(data)  # 存入数据库
            # 发布redis
            self.redis_helper.pub_msg(func, data, channel=CHANNEL_SPIDER)
            # func->key: 去掉update_
            self.last_data[str(func).split("update_")[-1]] = data
            self.send_msg(func, data)

    def send_msg(self, key, msg):
        self.mutex.acquire()
        for _, handler in self.handlers.items():
            try:
                handler.send_msg(key, msg)
            except:
                pass
        self.mutex.release()

radiocaca_manager = RadiocacaManager()
